package com.example.weixinsystem.service.impl;

import cn.hutool.core.date.DateUtil;
import com.example.weixinsystem.service.LoginService;
import com.weixin.common.core.constant.TokenConstant;
import com.weixin.common.core.exception.BaseException;
import com.weixin.common.core.form.LoginForm;
import com.weixin.common.core.form.LoginUserDetails;
import com.weixin.common.core.utils.JwtUtils;
import com.weixin.common.core.utils.SecurityUtil;
import com.weixin.common.core.utils.StringUtil;
import com.weixin.common.core.utils.TokenUtil;
import com.weixin.common.redis.service.RedisService;
import com.weixin.common.security.service.TokenService;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @version 1.0.0
 * @className: LoginServiceImpl
 * @description: 用户登录服务
 * @author: zhangjunfa
 * @date: 2023/5/27 15:28
 */
@Service
public class LoginServiceImpl implements LoginService {

    private AuthenticationManager authenticationManager;
    private RedisService redisService;
    private TokenService tokenService;

    public LoginServiceImpl(AuthenticationManager authenticationManager, RedisService redisService, TokenService tokenService) {
        this.authenticationManager = authenticationManager;
        this.redisService = redisService;
        this.tokenService = tokenService;
    }

    /**
     * 用户登录
     *
     * @param loginForm 登录对象
     * @return
     */
    @Override
    public String login(LoginForm loginForm) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginForm.getUserName(), loginForm.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new BaseException("用户名或密码错误");
        }

        //使用userid生成token
        LoginUserDetails loginUser = (LoginUserDetails) authenticate.getPrincipal();
        // 用户唯一标识
        String token = StringUtil.fastUUID();
        // 用户唯一标识
        loginUser.setToken(token);
        // 登录时间
        loginUser.setLoginTime(DateUtil.current());
        // 刷新 redis 令牌有效期
        this.tokenService.refreshToken(loginUser);

        Map<String, Object> clamis = new HashMap<>();
        clamis.put(TokenConstant.LOGIN_USER_KEY, token);
        JwtUtils.createToken(clamis);
        return token;
    }

    /**
     * 刷新令牌有效期
     *
     * @param request 登录信息
     */
    @Override
    public void refreshToken(HttpServletRequest request) {
        String token = SecurityUtil.getToken(request);
        String redisCacheKey = TokenUtil.getRedisCacheKey(token);
        LoginUserDetails userDetails = this.redisService.getCacheObject(redisCacheKey);
        if (Objects.isNull(userDetails)) {
            throw new BaseException("刷新令牌错误！");
        }
        // 刷新令牌有效期
        tokenService.refreshToken(userDetails);
    }

    /**
     * 退出登录
     *
     * @param request 请求头
     */
    @Override
    public void logout(HttpServletRequest request) {
        String token = SecurityUtil.getToken(request);
        String redisCacheKey = TokenUtil.getRedisCacheKey(token);
        this.tokenService.delToken(redisCacheKey);
    }

}
